/* Copyright (c) 2004-2024 peigen.info. All rights reserved. */

package info.peigen.hotpot.manage.core.repository.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import info.peigen.hotpot.common.core.result.ResultCode;
import info.peigen.hotpot.common.service.base.exception.BusinessException;
import info.peigen.hotpot.component.data.repository.beetlsql.service.AbstractBeetlSqlRepository;
import info.peigen.hotpot.manage.core.domain.Organization;
import info.peigen.hotpot.manage.core.domain.Position;
import info.peigen.hotpot.manage.core.domain.Role;
import info.peigen.hotpot.manage.core.domain.User;
import info.peigen.hotpot.manage.core.repository.entity.OrganizationEntity;
import info.peigen.hotpot.manage.core.repository.entity.PositionEntity;
import info.peigen.hotpot.manage.core.repository.entity.RoleEntity;
import info.peigen.hotpot.manage.core.repository.entity.UserEntity;
import info.peigen.hotpot.manage.core.repository.mapper.UserMapper;
import info.peigen.hotpot.manage.core.util.convertor.OrganizationConvertor;
import info.peigen.hotpot.manage.core.util.convertor.PositionConvertor;
import info.peigen.hotpot.manage.core.util.convertor.RoleConvertor;
import info.peigen.hotpot.manage.core.util.convertor.UserConvertor;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;

import java.util.List;

/**
 * <b>(UserRepository)</b>
 * "用户" 仓储服务
 *
 * @author Peigen
 * @version 1.0.0
 * @since 2024-06-28
 */
@SuppressWarnings("unused")
@Component
public class UserRepository extends AbstractBeetlSqlRepository<UserMapper, UserEntity> {
    @Inject
    RoleRepository roleRepository;

    @Inject
    PositionRepository positionRepository;

    @Inject
    OrganizationRepository organizationRepository;

    public User active(String userId) {
        Assert.isTrue(StrUtil.isNotEmpty(userId), () -> new BusinessException(ResultCode.FAILURE, "激活时[userId]不得为空!"));
        UserEntity entity = getMapper().findByUserId(userId);
        Assert.notNull(entity, () -> new BusinessException(ResultCode.FAILURE, "激活失败!userId=" + userId));

        User domain = UserConvertor.INSTANCE.convertToDomain(entity);

        // Role
        List<RoleEntity> roleEntities = roleRepository.getMapper()
                .listByRoleIds(StrUtil.split(entity.getRoleIds(), ",").stream().toList());
        List<Role> roleDomains = RoleConvertor.INSTANCE.convertToDomainsByEntity(roleEntities);
        domain.setRoles(roleDomains);

        // Position
        List<PositionEntity> positionEntities = positionRepository.getMapper()
                .listByPositionIds(StrUtil.split(entity.getPositionIds(), ",").stream().toList());
        List<Position> positionDomains = PositionConvertor.INSTANCE.convertToDomainsByEntity(positionEntities);
        domain.setPositions(positionDomains);

        // Organization
        List<OrganizationEntity> organizationEntities = organizationRepository.getMapper()
                .listByOrganizationIds(StrUtil.split(entity.getOrganizationIds(), ",").stream().toList());
        List<Organization> organizationDomains = OrganizationConvertor.INSTANCE.convertToDomainsByEntity(organizationEntities);
        domain.setOrganizations(organizationDomains);
        return domain;
    }

    public User activeByLoginName(String loginName) {
        Assert.isTrue(StrUtil.isNotEmpty(loginName), () -> new BusinessException(ResultCode.FAILURE, "激活时[loginName]不得为空!"));
        UserEntity entity = getMapper().findByLoginName(loginName);
        return active(entity.getUserId());
    }

    public List<User> active(List<String> userIds) {
        Assert.isTrue(CollUtil.isNotEmpty(userIds), () -> new BusinessException(ResultCode.FAILURE, "激活时[userIds]不得为空!"));
        List<UserEntity> entities = getMapper().listByUserIds(userIds);
        Assert.notNull(entities, () -> new BusinessException(ResultCode.FAILURE, "激活失败!userId=" + userIds));

        return UserConvertor.INSTANCE.convertToDomainsByEntity(entities);

    }

    public User lock(String userId) {
        Assert.isTrue(StrUtil.isNotEmpty(userId), () -> new BusinessException(ResultCode.FAILURE, "加锁时[userId]不得为空!"));
        UserEntity entity = getMapper().lockByUserId(userId);
        Assert.notNull(entity, () -> new BusinessException(ResultCode.FAILURE, "锁定失败!userId为空!"));
        return UserConvertor.INSTANCE.convertToDomain(entity);
    }

    public void removeByUserId(String userId) {
        Assert.isTrue(StrUtil.isNotEmpty(userId), () -> new BusinessException(ResultCode.FAILURE, "删除时[userId]不得为空!"));
        getMapper().deleteByUserId(userId);
    }

    public void logicDeleteById(Integer id) {
        delete(id);
    }

    public int logicDeleteByUserId(String userId) {
        Assert.isTrue(StrUtil.isNotEmpty(userId), () -> new BusinessException(ResultCode.FAILURE, "逻辑删除时[userId]不得为空!"));
        return getMapper().createLambdaQuery().andEq(UserEntity::getUserId, userId).delete();
    }

    public void store(User domain) {
        Assert.isTrue(ObjectUtil.isNotEmpty(domain), () -> new BusinessException(ResultCode.FAILURE, "持久化时[domain]不得为空!"));
        UserEntity entity = UserConvertor.INSTANCE.convertToEntity(domain);
        saveOrUpdate(entity);
    }

}